package org.linlinjava.litemall.admin.service;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.sql.Wrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Editor;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.shiro.SecurityUtils;
import org.linlinjava.litemall.admin.beans.dto.ShopMerchandiseSetWarnNumDto;
import org.linlinjava.litemall.admin.errorcode.ErrorCodeConstants;
import org.linlinjava.litemall.admin.util.AdminResponseEnum;
import org.linlinjava.litemall.admin.vo.merchandise.MerchandiseImportExcelVO;
import org.linlinjava.litemall.admin.vo.shopmerchandise.ShopMerchandiseStatisticsReqVO;
import org.linlinjava.litemall.admin.vo.shopmerchandise.ShopMerchandiseTotalStatisticsVO;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.vo.shopmerchandise.ConsumerStatisticsVO;
import org.linlinjava.litemall.db.vo.shopmerchandise.InNumStatisticsVO;
import org.linlinjava.litemall.db.vo.shopmerchandise.LossStatisticsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;

import static org.linlinjava.litemall.core.exception.util.ServiceExceptionUtil.exception;

/**
 * 商店商品服务
 * 门店服务
 *
 * @author yliyun
 * @date 2022/09/14
 */
@Service
@RequiredArgsConstructor
@Transactional
public class ShopMerchandiseService {

    private final LitemallMerchandiseService litemallMerchandiseService;
    private final LumiereMerchandiseImportService lumiereMerchandiseImportService;

    private final LumiereMerchandiseService lumiereMerchandiseService;
    private final LumiereFormulaMaterialService lumiereFormulaMaterialService;

	private final LitemallShopMerchandiseService litemallShopMerchandiseService;
    private final LitemallShopService litemallShopService;
    private final LumiereMaterialClassificationService lumiereMaterialClassificationService;
    private final LitemallOrderFormulaMaterialService litemallOrderFormulaMaterialService;

    private final LitemallOrderGoodsService litemallOrderGoodsService;


    public Object list(Integer shopId,String name,
    		String merchandiseSn,Integer waning, int page, int limit) {

        IPage<LitemallShopMerchandiseVo> result = litemallShopMerchandiseService.selectJoinListPage(new Page(page, limit), LitemallShopMerchandiseVo.class, new MPJLambdaWrapper<LitemallShopMerchandise>()
                .selectAll(LitemallShopMerchandise.class)
                .selectAs(LitemallMerchandise::getMerchandiseSn, LitemallShopMerchandiseVo::getMerchandiseSn)
                .selectAs(LitemallMerchandise::getName, LitemallShopMerchandiseVo::getName)
                .selectAs(LitemallMerchandise::getPicUrl, LitemallShopMerchandiseVo::getPicUrl)
                .selectAs(LitemallMerchandise::getSellingPrice, LitemallShopMerchandiseVo::getSellingPrice)
                .selectAs(LitemallMerchandise::getPurchasePrice, LitemallShopMerchandiseVo::getPurchasePrice)
                .selectAs(LitemallMerchandise::getStandard, LitemallShopMerchandiseVo::getStandard)
                .selectAs(LitemallMerchandise::getNumber, LitemallShopMerchandiseVo::getMerchandiseNumber)
                .selectAs(LitemallMerchandise::getModel, LitemallShopMerchandiseVo::getModel)
                .selectAs(LitemallMerchandise::getBasicUnit, LitemallShopMerchandiseVo::getBasicUnit)
                .selectAs(LitemallMerchandise::getCheckUnit, LitemallShopMerchandiseVo::getCheckUnit)
                .selectAs(LitemallMerchandise::getCheckRatio, LitemallShopMerchandiseVo::getCheckRatio)
                .selectAs(LitemallMerchandise::getUnit, LitemallShopMerchandiseVo::getUnit)
                .selectAs(LitemallMerchandise::getRatio, LitemallShopMerchandiseVo::getRatio)
                .leftJoin(LitemallMerchandise.class, LitemallMerchandise::getId, LitemallShopMerchandise::getMerchandiseId)

                .eq(shopId != null, LitemallShopMerchandise::getShopId, shopId)
                .like(merchandiseSn != null, LitemallMerchandise::getMerchandiseSn, merchandiseSn)
                .like(name != null, LitemallMerchandise::getName, name)
                .ge(waning != null && waning == 1, LitemallShopMerchandise::getWarnNumber, LitemallShopMerchandise::getNumber)
                .or(waning != null && waning == 2, w -> w.lt(LitemallShopMerchandise::getWarnNumber, LitemallShopMerchandise::getNumber))
                .or(waning != null && waning == 2, w -> w.isNull(LitemallShopMerchandise::getWarnNumber))
                .orderByDesc(LitemallShopMerchandise::getAddTime)
        );
        //List<LitemallShopMerchandiseVo> result = litemallShopMerchandiseService.queryByMerchandiseSnAndName(shopId, name, merchandiseSn, waning, page, limit);
        result.getRecords().stream().forEach(shopMerchandiseVo->{
            shopMerchandiseVo.setShopName(litemallShopService.findById(shopMerchandiseVo.getShopId()).getName());
        });
        return ResponseUtil.okPage(result);
    }

    public Object setWarnNumber(ShopMerchandiseSetWarnNumDto shopMerchandiseSetWarnNumDto) {
    	Integer id = shopMerchandiseSetWarnNumDto.getId();
    	LitemallShopMerchandise merchandise = litemallShopMerchandiseService.findById(id);
    	if(null == merchandise) {
    		return ResponseUtil.fail(AdminResponseEnum.SHOP_MERCHANDISE_NOT_EXIST.getCode(), AdminResponseEnum.SHOP_MERCHANDISE_NOT_EXIST.getMsg());
    	}

    	merchandise.setWarnNumber(shopMerchandiseSetWarnNumDto.getWarnNumber());
        merchandise.setLossValue(shopMerchandiseSetWarnNumDto.getLossValue());
    	litemallShopMerchandiseService.updateById(merchandise);
    	return ResponseUtil.ok();
    }

    public ResponseUtil.Response totalStatistics(ShopMerchandiseStatisticsReqVO reqVO) {
        ShopMerchandiseTotalStatisticsVO totalStatistics = new ShopMerchandiseTotalStatisticsVO();
        // 生成基础查询条件
        LambdaQueryWrapper<LitemallMerchandise> baseQuery = new LambdaQueryWrapper<>();
        if (reqVO.getShopId() != null) {
            baseQuery.eq(LitemallMerchandise::getShopId, reqVO.getShopId());
        }
        if (reqVO.getMerchandiseSn() != null) {
            baseQuery.like(LitemallMerchandise::getMerchandiseSn, reqVO.getMerchandiseSn());
        }
        if (reqVO.getMerchandiseName() != null) {
            baseQuery.like(LitemallMerchandise::getName, reqVO.getMerchandiseName());
        }
        baseQuery.orderByDesc(LitemallMerchandise::getAddTime);
        // 查询商品基础信息
        IPage<LitemallMerchandise> merchandiseList = litemallMerchandiseService.page(new Page<>(reqVO.getPage(), reqVO.getLimit()),baseQuery);
        Double totalMerchandiseQuantity = merchandiseList.getRecords().stream()
                .mapToDouble(LitemallMerchandise::getNumber)
                .sum();
        totalStatistics.setTotalMerchandiseNum(totalMerchandiseQuantity);

        // 统计 inNum 和 avgInNum
        List<InNumStatisticsVO> inNumList = litemallMerchandiseService.getInNumStatistics(reqVO.getBeginTime(), reqVO.getEndTime());
        BigDecimal totalInNum = inNumList.stream()
                .map(InNumStatisticsVO::getInNum)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        totalStatistics.setTotalInNum(totalInNum);

        // 统计 consumerNum 和 avgConsumerNum
        List<ConsumerStatisticsVO> consumerList = litemallMerchandiseService.getConsumerStatistics(reqVO.getBeginTime(), reqVO.getEndTime());
        BigDecimal totalConsumerNum = consumerList.stream()
                .map(ConsumerStatisticsVO::getConsumerNum)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        totalStatistics.setTotalConsumerNum(totalConsumerNum);

        // 统计 lossNum 和 avgLossNum
        List<LossStatisticsVO> lossList = litemallMerchandiseService.getLossStatistics(reqVO.getBeginTime(), reqVO.getEndTime());
        BigDecimal totalLossNum = lossList.stream()
                .map(LossStatisticsVO::getLossNum)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        totalStatistics.setTotalLossNum(totalLossNum);

        return ResponseUtil.ok(totalStatistics);
    }


    public Object statistics(ShopMerchandiseStatisticsReqVO reqVO) {

        // 生成基础查询条件
        LambdaQueryWrapper<LitemallShopMerchandise> baseQuery = new LambdaQueryWrapper<>();
        baseQuery.eq(reqVO.getShopId() != null,LitemallShopMerchandise::getShopId, reqVO.getShopId());
        IPage<LitemallShopMerchandise> shopMerchandiseList = litemallShopMerchandiseService.page(new Page<>(reqVO.getPage(), reqVO.getLimit()),baseQuery);
        List<ShopMerchandiseStatisticsVo> shopMerchandiseStatisticsList = CollStreamUtil.toList(shopMerchandiseList.getRecords(),shopMerchandise -> {
            LitemallMerchandise merchandise = litemallMerchandiseService.findById(shopMerchandise.getMerchandiseId());
            List<LitemallOrderFormulaMaterial> orderFormulaMaterials = litemallOrderFormulaMaterialService.selectByOrderMaterialIdList(merchandise.getId());
            //消耗量(盘点单位)
            BigDecimal consumerNum = BigDecimal.ZERO;
            //损耗量(盘点单位)
            BigDecimal lossNum = BigDecimal.ZERO;
            for (LitemallOrderFormulaMaterial orderFormulaMaterial : orderFormulaMaterials) {
                LitemallOrderGoods orderGoods = litemallOrderGoodsService.findById(orderFormulaMaterial.getOrderGoodsId());
                //单次消耗剂量
                Double onceConsumedDose = orderGoods.getNumber() * orderFormulaMaterial.getSpecificationsDose() * orderFormulaMaterial.getQuantity();
                //单次损耗剂量
                BigDecimal onceLossDose = orderFormulaMaterial.getConsumeSystem().multiply(new BigDecimal(onceConsumedDose));
                //单次使用剂量
                BigDecimal onceUseDose = new BigDecimal(onceConsumedDose).subtract(onceLossDose);
                consumerNum = consumerNum.add(onceUseDose);
                lossNum = lossNum.add(onceLossDose);
            }


            ShopMerchandiseStatisticsVo statisticsVo = new ShopMerchandiseStatisticsVo();
            statisticsVo.setStandard(merchandise.getStandard());
            statisticsVo.setMerchandiseId(merchandise.getId());
            statisticsVo.setMerchandiseSn(merchandise.getMerchandiseSn());
            statisticsVo.setMerchandiseName(merchandise.getName());
            statisticsVo.setUnit(merchandise.getBasicUnit());

            // 设置 inNum 和 avgInNum
            statisticsVo.setInNum(new BigDecimal(shopMerchandise.getBasicNumber()));

            // 设置 consumerNum 和 avgConsumerNum
            statisticsVo.setConsumerNum(consumerNum);

            // 设置 lossNum 和 avgLossNum
            statisticsVo.setLossNum(lossNum);

            return statisticsVo;
        });
        return ResponseUtil.okPage(shopMerchandiseList,shopMerchandiseStatisticsList);



        // 生成基础查询条件
        /*LambdaQueryWrapper<LitemallMerchandise> baseQuery = new LambdaQueryWrapper<>();
        if (reqVO.getShopId() != null) {
            baseQuery.eq(LitemallMerchandise::getShopId, reqVO.getShopId());
        }
        if (reqVO.getMerchandiseSn() != null) {
            baseQuery.like(LitemallMerchandise::getMerchandiseSn, reqVO.getMerchandiseSn());
        }
        if (reqVO.getMerchandiseName() != null) {
            baseQuery.like(LitemallMerchandise::getName, reqVO.getMerchandiseName());
        }
        baseQuery.orderByDesc(LitemallMerchandise::getAddTime);

        // 查询商品基础信息
        IPage<LitemallMerchandise> merchandiseList = litemallMerchandiseService.page(new Page<>(reqVO.getPage(), reqVO.getLimit()),baseQuery);

        // 统计 inNum 和 avgInNum
        List<InNumStatisticsVO> inNumList = litemallMerchandiseService.getInNumStatistics(reqVO.getBeginTime(), reqVO.getEndTime());
        // 统计 consumerNum 和 avgConsumerNum
        List<ConsumerStatisticsVO> consumerList = litemallMerchandiseService.getConsumerStatistics(reqVO.getBeginTime(), reqVO.getEndTime());

        // 统计 lossNum 和 avgLossNum
        List<LossStatisticsVO> lossList = litemallMerchandiseService.getLossStatistics(reqVO.getBeginTime(), reqVO.getEndTime());

        // 合并统计结果
        List shopMerchandiseStatisticsVos = mergeStatistics(merchandiseList.getRecords(), inNumList, consumerList, lossList, reqVO.getBeginTime(), reqVO.getEndTime());
        merchandiseList.setRecords(shopMerchandiseStatisticsVos);
        return ResponseUtil.okPage(merchandiseList);*/

    	//List<ShopMerchandiseStatisticsVo> result = litemallShopMerchandiseService.statistics(reqVO.getShopId(), reqVO.getMerchandiseName(), reqVO.getMerchandiseSn(), null, null, reqVO.getPage(), reqVO.getLimit());
        //return ResponseUtil.okList(result);
    }

    private List<ShopMerchandiseStatisticsVo> mergeStatistics(List<LitemallMerchandise> merchandiseList,
                                                          List<InNumStatisticsVO> inNumList,
                                                          List<ConsumerStatisticsVO> consumerList,
                                                          List<LossStatisticsVO> lossList,
                                                          String beginTime,
                                                          String endTime) {
        // 将统计数据整合到最终结果中
        int dateDiff = getDateDiff(beginTime, endTime);
        //int dateDiff = 8;
        return CollStreamUtil.toList(merchandiseList,merchandise -> {
            ShopMerchandiseStatisticsVo statisticsVo = new ShopMerchandiseStatisticsVo();
            /*statisticsVo.setShopId(merchandise.getShopId());
            LitemallShop shop = litemallShopService.findById(merchandise.getShopId());
            statisticsVo.setShopName(shop!=null? shop.getName():null);*/
            statisticsVo.setStandard(merchandise.getStandard());
            statisticsVo.setMerchandiseId(merchandise.getId());
            statisticsVo.setMerchandiseSn(merchandise.getMerchandiseSn());
            statisticsVo.setMerchandiseName(merchandise.getName());
            statisticsVo.setUnit(merchandise.getUnit());

            // 设置 inNum 和 avgInNum
            InNumStatisticsVO inNum = findInNum(inNumList, merchandise.getId(), merchandise.getShopId());
            statisticsVo.setInNum(inNum != null ? inNum.getInNum() : BigDecimal.ZERO);
            statisticsVo.setAvgInNum(inNum != null ? inNum.getInNum().divide(BigDecimal.valueOf(dateDiff), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);

            // 设置 consumerNum 和 avgConsumerNum
            ConsumerStatisticsVO consumer = findConsumer(consumerList, merchandise.getId(), merchandise.getShopId());
            statisticsVo.setConsumerNum(consumer != null ? consumer.getConsumerNum() : BigDecimal.ZERO);
            statisticsVo.setAvgConsumerNum(consumer != null ? consumer.getConsumerNum().divide(BigDecimal.valueOf(dateDiff), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);

            // 设置 lossNum 和 avgLossNum
            LossStatisticsVO loss = findLoss(lossList, merchandise.getId(), merchandise.getShopId());
            statisticsVo.setLossNum(loss != null ? loss.getLossNum() : BigDecimal.ZERO);
            statisticsVo.setAvgLossNum(loss != null ? loss.getLossNum().divide(BigDecimal.valueOf(dateDiff), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);

            return statisticsVo;
        });
    }

    private int getDateDiff(String beginTime, String endTime) {
        // 日期差计算逻辑
        return (int) DateUtil.between(DateUtil.parse(beginTime), DateUtil.parse(endTime), DateUnit.DAY);
    }

    private InNumStatisticsVO findInNum(List<InNumStatisticsVO> inNumList, Integer merchandiseId, Integer shopId) {
        return inNumList.stream().filter(i -> i.getMerchandiseId().equals(merchandiseId) )
                .findFirst().orElse(null);
    }

    private ConsumerStatisticsVO findConsumer(List<ConsumerStatisticsVO> consumerList, Integer merchandiseId, Integer shopId) {
        return consumerList.stream().filter(i -> i.getMerchandiseId().equals(merchandiseId) )
                .findFirst().orElse(null);
    }

    private LossStatisticsVO findLoss(List<LossStatisticsVO> lossList, Integer merchandiseId, Integer shopId) {
        return lossList.stream().filter(i -> i.getMerchandiseId().equals(merchandiseId) )
                .findFirst().orElse(null);
    }



    public Object importMerchandiseList(List<MerchandiseImportExcelVO> importMerchandises, Integer shopId) {
        // 使用 Java Stream API 对列表进行过滤
        importMerchandises = importMerchandises.stream()
                .filter(importMerchandise ->
                        StrUtil.isNotEmpty(importMerchandise.getClassification()) &&
                                StrUtil.isNotEmpty(importMerchandise.getName()))
                .collect(Collectors.toList());

        // 1.1 参数校验
        if (CollUtil.isEmpty(importMerchandises)) {
            throw exception(ErrorCodeConstants.MERCHANDISE_IMPORT_LIST_IS_EMPTY);
        }
        List<LitemallMerchandise> litemallMerchandiseList = litemallMerchandiseService.selectList(Wrappers.lambdaQuery(LitemallMerchandise.class));

        List<LitemallMerchandise> merchandiseList = new ArrayList<>(importMerchandises.size());
        for (MerchandiseImportExcelVO importMerchandise : importMerchandises) {
            if(StrUtil.isEmpty(importMerchandise.getName())||StrUtil.isEmpty(importMerchandise.getClassification()))continue;
            //给门店添加库存,存在则改变数量，不存在则新增
            LitemallMerchandise merchandise = CollUtil.findOne(litemallMerchandiseList, item -> item.getName().toLowerCase().equals(importMerchandise.getName().toLowerCase()));

            if(merchandise!=null){
                merchandise.setName(importMerchandise.getName());
                merchandise.setMerchandiseSn(importMerchandise.getSerial());
                merchandise.setClassification(importMerchandise.getClassification());
                merchandise.setBasicUnit(importMerchandise.getBaseUnit());
                merchandise.setCheckUnit(importMerchandise.getCheckUnit());
                merchandise.setUnit(importMerchandise.getUnit());
                merchandise.setCheckRatio(importMerchandise.getCheckRatio());
                merchandise.setRatio(importMerchandise.getRatio());
                merchandise.setPurchasePrice(importMerchandise.getPurchasePrice());
                merchandise.setSellingPrice(importMerchandise.getSellingPrice());
                merchandise.setStandard(importMerchandise.getStandard());

                merchandise.setNumber(merchandise.getNumber()+importMerchandise.getNumber());
                lumiereMerchandiseService.updateById(merchandise);
            }else {
                merchandise = new LitemallMerchandise();
                merchandise.setMerchandiseSn(importMerchandise.getSerial());
                merchandise.setName(importMerchandise.getName());
                merchandise.setClassification(importMerchandise.getClassification());
                merchandise.setLabel(importMerchandise.getLabel());
                merchandise.setBrand(importMerchandise.getBrand());

                merchandise.setStandard(importMerchandise.getStandard());
                merchandise.setBasicUnit(importMerchandise.getBaseUnit());
                merchandise.setCheckUnit(importMerchandise.getCheckUnit());
                merchandise.setPurchasePrice(importMerchandise.getPurchasePrice());
                merchandise.setSellingPrice(importMerchandise.getSellingPrice());
                merchandise.setNumber(importMerchandise.getNumber());
                merchandise.setUnit(importMerchandise.getUnit());
                merchandise.setRatio(importMerchandise.getRatio());
                merchandise.setCheckRatio(importMerchandise.getCheckRatio());
                lumiereMerchandiseService.save(merchandise);
            }
            merchandiseList.add(merchandise);
        }
        //导入门店
        for (LitemallMerchandise merchandise : merchandiseList) {
            //给门店添加库存,存在则改变数量，不存在则新增
            LitemallShopMerchandise shopMerchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(merchandise.getId(), shopId);
            Double number = merchandise.getNumber()*merchandise.getRatio();//计算入库的数量(盘点单位)
            Double basicNumber = number*merchandise.getCheckRatio();//计算入库的数量(基本单位)
            if(shopMerchandise != null){
                shopMerchandise.setNumber(number);
                shopMerchandise.setBasicNumber(basicNumber);
                litemallShopMerchandiseService.updateById(shopMerchandise);
            }else{
                shopMerchandise = new LitemallShopMerchandise();
                shopMerchandise.setMerchandiseId(merchandise.getId());
                shopMerchandise.setNumber(number);
                shopMerchandise.setBasicNumber(basicNumber);
                shopMerchandise.setSellPrice(merchandise.getSellingPrice());
                shopMerchandise.setShopId(shopId);
                litemallShopMerchandiseService.create(shopMerchandise);
            }
        }

        //导入新的原料分类
        importMerchandisesClassification(importMerchandises);
        //导入配方原料表
        importFormulaMerchandises(merchandiseList);
        //记录excel进货的原料
        insertImportMerchandises(importMerchandises,shopId);
        return ResponseUtil.ok();
    }

    private void insertImportMerchandises(List<MerchandiseImportExcelVO> importMerchandiseList, Integer shopId){
        //所有已导入的原料
        List<LumiereMerchandiseImport> merchandiseImportList = lumiereMerchandiseImportService.list(Wrappers.lambdaQuery(LumiereMerchandiseImport.class));
        for (MerchandiseImportExcelVO importMerchandise : importMerchandiseList) {
            //给门店添加库存,存在则改变数量，不存在则新增
            LumiereMerchandiseImport merchandise = CollUtil.findOne(merchandiseImportList, item -> item.getShopId().intValue() == shopId && item.getName().toLowerCase().equals(importMerchandise.getName().toLowerCase()));

            if(merchandise!=null){
                merchandise.setShopId(shopId);
                merchandise.setName(importMerchandise.getName());
                merchandise.setMerchandiseSn(importMerchandise.getSerial());
                merchandise.setClassification(importMerchandise.getClassification());
                merchandise.setBasicUnit(importMerchandise.getBaseUnit());
                merchandise.setCheckUnit(importMerchandise.getCheckUnit());
                merchandise.setUnit(importMerchandise.getUnit());
                merchandise.setCheckRatio(importMerchandise.getCheckRatio());
                merchandise.setRatio(importMerchandise.getRatio());
                merchandise.setPurchasePrice(importMerchandise.getPurchasePrice());
                merchandise.setSellingPrice(importMerchandise.getSellingPrice());
                merchandise.setStandard(importMerchandise.getStandard());

                merchandise.setNumber(merchandise.getNumber()+importMerchandise.getNumber());
                lumiereMerchandiseImportService.updateById(merchandise);
            }else {
                merchandise = new LumiereMerchandiseImport();
                merchandise.setShopId(shopId);
                merchandise.setMerchandiseSn(importMerchandise.getSerial());
                merchandise.setName(importMerchandise.getName());
                merchandise.setClassification(importMerchandise.getClassification());
                merchandise.setLabel(importMerchandise.getLabel());
                merchandise.setBrand(importMerchandise.getBrand());

                merchandise.setStandard(importMerchandise.getStandard());
                merchandise.setBasicUnit(importMerchandise.getBaseUnit());
                merchandise.setCheckUnit(importMerchandise.getCheckUnit());
                merchandise.setPurchasePrice(importMerchandise.getPurchasePrice());
                merchandise.setSellingPrice(importMerchandise.getSellingPrice());
                merchandise.setNumber(importMerchandise.getNumber());
                merchandise.setUnit(importMerchandise.getUnit());
                merchandise.setRatio(importMerchandise.getRatio());
                merchandise.setCheckRatio(importMerchandise.getCheckRatio());
                lumiereMerchandiseImportService.save(merchandise);
            }
        }
    }

    private void importFormulaMerchandises(List<LitemallMerchandise> merchandiseList){

        CollUtil.filter(merchandiseList, (Filter<LitemallMerchandise>) merchandise -> {
            List<LumiereFormulaMaterial> formulaMaterials = lumiereFormulaMaterialService.list(Wrappers.lambdaQuery(LumiereFormulaMaterial.class).eq(LumiereFormulaMaterial::getMaterialName, merchandise.getName()));
            return formulaMaterials.size() == 0;
        });

        List<LumiereFormulaMaterial> formulaMaterialList = CollStreamUtil.toList(merchandiseList, merchandise -> {
            return new LumiereFormulaMaterial().setMaterialId(merchandise.getId())
                    .setMaterialName(merchandise.getName())
                    .setMaterialImg(merchandise.getPicUrl())
                    .setMaterialClassificationName(merchandise.getClassification()).setUnit(merchandise.getBasicUnit());
        });
        lumiereFormulaMaterialService.saveBatch(formulaMaterialList);
    }

    private void importMerchandisesClassification (List<MerchandiseImportExcelVO> importMerchandises){
        //新增原料分类
        for (MerchandiseImportExcelVO importMerchandise : importMerchandises) {
            List<LumiereMaterialClassification> materialClassificationList = lumiereMaterialClassificationService.list(Wrappers.lambdaQuery(LumiereMaterialClassification.class)
                    .isNull(LumiereMaterialClassification::getPid)
                    .eq(LumiereMaterialClassification::getClassificationName, importMerchandise.getClassification()));
            if(materialClassificationList.size()==0){
                //没有这种分类，新增
                lumiereMaterialClassificationService.save(new LumiereMaterialClassification()
                        .setClassificationName(importMerchandise.getClassification()).setNumber(1).setPid(null).setClassificationColour(getColor()));
            }
        }

    }

    //随机生成颜色代码
    public String getColor(){
        //红色
        String red;
        //绿色
        String green;
        //蓝色
        String blue;
        //生成随机对象
        Random random = new Random();
        //生成红色颜色代码
        red = Integer.toHexString(random.nextInt(256)).toUpperCase();
        //生成绿色颜色代码
        green = Integer.toHexString(random.nextInt(256)).toUpperCase();
        //生成蓝色颜色代码
        blue = Integer.toHexString(random.nextInt(256)).toUpperCase();

        //判断红色代码的位数
        red = red.length()==1 ? "0" + red : red ;
        //判断绿色代码的位数
        green = green.length()==1 ? "0" + green : green ;
        //判断蓝色代码的位数
        blue = blue.length()==1 ? "0" + blue : blue ;
        //生成十六进制颜色值
        String color = "#"+red+green+blue;
        List<LumiereMaterialClassification> list = lumiereMaterialClassificationService.list(Wrappers.lambdaQuery(LumiereMaterialClassification.class)
                .eq(LumiereMaterialClassification::getClassificationColour, color));
        while (list.size()>0){
            color = getColor();
        }
        return color;
    }

    public void export(HttpServletResponse response, String filename, String sheetName, List<MerchandiseImportExcelVO> data) throws IOException {
        //获取需要导出的数据
        //excel文件名
        final String FILENAME = filename;
        //sheetName
        final String SHEETNAME = sheetName;
        //获取model对象类
        try {
            //表头样式策略
            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
            //设置头居中
            headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            //内容策略
            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
            //设置 水平居中
            contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
            //初始化表格样式
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

//                response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode(FILENAME, "UTF-8").replaceAll("\\+", "%20");
            //响应首部 Access-Control-Expose-Headers 就是控制“暴露”的开关，它列出了哪些首部可以作为响应的一部分暴露给外部。
            //此处设置了开放Content-Disposition，前端可获取该响应参数获取文件名称
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");
            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream(), MerchandiseImportExcelVO.class).autoCloseStream(Boolean.FALSE)
                    .registerWriteHandler(horizontalCellStyleStrategy).sheet(SHEETNAME).doWrite(data);

        } catch (IOException e) { //下载失败情况的处理
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = MapUtils.newHashMap();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        }
    }
}
